#include <QThread>
#include <cmath>

#include "livemasterwidget.h"
#include "ui_livemasterwidget.h"
#include "mainwidget.h"
#include "capturethread.h"
#include "mycameraabs.h"
#include "../MyTcp2/tcpsession.h"


LiveMasterWidget::LiveMasterWidget(TcpSession* session, MainWidget* mainWidget, QWidget *parent) :
    QWidget(parent), ui(new Ui::LiveMasterWidget), mainWidget(mainWidget),session(session)
{
    ui->setupUi(this);
    picid=0;
    QObject::connect(session, &TcpSession::houseMems_signal, this, &LiveMasterWidget::on_houseMems_signal);
    QObject::connect(session, &TcpSession::houseMsg_signal, this, &LiveMasterWidget::on_houseMsg_signal);
    QObject::connect(session, &TcpSession::logout_call_signal, this, &LiveMasterWidget::on_logout_call_signal);

    //
    QCameraInfo info = QCameraInfo::defaultCamera();
    camera = new QCamera(info,this);
    myCameraABS = new MyCameraABS(this);
    QObject::connect(myCameraABS,&MyCameraABS::camera_signal,this,&LiveMasterWidget::on_camera_signal);
    camera->setViewfinder(myCameraABS);
}


void LiveMasterWidget::show(QString &username, QString & nickname, QString& housename, int & houseID)
{
    this->username = username;
    this->nickname = nickname;
    this->housename=housename;
    this->houseID=houseID;
    picid=0;
    //界面初始化
    this->setWindowTitle(housename);
    ui->listWidget->clear();
    ui->textBrowser->clear();

    //查询房间的基本信息
    Pack pack;
    pack.setType(HOUSE_ENTER);
    pack.setFrame(CALL);
    pack.append(username);
    pack.append(nickname);
    pack.append(QString::number(houseID));
    pack.append(housename);
    session->send((char*)&pack, pack.getPacksize());

    this->QWidget::show();
}


//界面事件：退出房间
void LiveMasterWidget::on_pushButton_exit_clicked()
{
    //发送退出房间的报文
    Pack pack(HOUSE_EXIT, CALL);
    pack.append(username);
    pack.append(nickname);
    pack.append(QString::number(houseID));
    session->send((char*)&pack, pack.getPacksize());
    //
    //停止直播
    if(thread != nullptr){
        thread->terminate();
        delete thread;
        thread=nullptr;
    }
    //关闭摄像头
    camera->stop();
    //切换界面
    this->hide();
    mainWidget->show();
}

//界面事件：开始直播
void LiveMasterWidget::on_pushButton_start_clicked()
{
    if(thread == nullptr){
        thread = new CaptureThread(session, this);

        QObject::connect(thread, &CaptureThread::pixCaptured, this, &LiveMasterWidget::onPixCaptured);
        thread->start();
    }
}

//界面事件：暂停直播
void LiveMasterWidget::on_pushButton_stop_clicked()
{
    if(thread != nullptr){
        thread->terminate();
        delete thread;
        thread=nullptr;
    }
    QMessageBox::information(this, "提示", "直播已暂停");
    ui->label->clear();
}

//界面事件：关闭摄像头
void LiveMasterWidget::on_pushButton_camera_close_clicked()
{
    camera->stop();
    QMessageBox::information(this, "提示", "摄像头已经关闭");
    ui->label_camera->clear();
}

//界面事件：打开摄像头
void LiveMasterWidget::on_pushButton_camera_open_clicked()
{
    camera->start();
}

//槽函数：成员列表
void LiveMasterWidget::on_houseMems_signal(const QStringList &fields)
{
    ui->listWidget->clear();
    for(const QString & str: fields)
        ui->listWidget->addItem(str);
}

//槽函数：房间消息
void LiveMasterWidget::on_houseMsg_signal(const QString &msg)
{
    ui->textBrowser->append(msg);
}

//槽函数：摄像头拍到图片
void LiveMasterWidget::on_camera_signal(QPixmap &pic)
{
    //本地显示
    pic=pic.scaled(ui->label_camera->size());
    ui->label_camera->setPixmap(pic);


    //TODO 尝试使用opencv把背景图扣掉

    //网络数据发送
    // pic 先转换成 QByteArray
    QByteArray byteArr;
    QBuffer buf(&byteArr);// 以arr为缓存区，创建buf，实现的效果是，写入buf中的数据，其实就是写入 arr 中
    pic.save(&buf,"jpg",50);
    //组包
    int size=byteArr.size();
    const int one=4000;
    int total= std::ceil(size*1.0/one);

    for(int packno=0 ; packno<total ; packno++){
        int bufCnt=4;
        Pack pack;
        pack.setType(CAMERA);
        bufCnt+=4;
        pack.setFrame(CALL);
        bufCnt+=4;
        //特殊处理
        //房间号
        memcpy((char*)&pack+bufCnt, &houseID, 4);
        bufCnt+=4;
        //图片编号
        memcpy((char*)&pack+bufCnt, &picid, 4);
        bufCnt+=4;
        //总包数
        memcpy((char*)&pack+bufCnt, &total, 4);
        bufCnt+=4;
        //当前包号
        memcpy((char*)&pack+bufCnt, &packno, 4);
        bufCnt+=4;
        if(packno == total-1){
            //buffer长度
            int left=size-(total-1)*one;
            memcpy((char*)&pack+bufCnt, &left, 4);
            bufCnt+=4;
            //buffer内容
            memcpy((char*)&pack+bufCnt, (char*)byteArr.data()+one*packno,left);
            bufCnt+=left;
        }else{
            //buffer长度
            memcpy((char*)&pack+bufCnt, &one, 4);
            bufCnt+=4;
            //buffer内容
            memcpy((char*)&pack+bufCnt, (char*)byteArr.data()+one*packno,one);
            bufCnt+=one;
        }
        pack.setPacksize(bufCnt);

        session->send((char*)&pack, pack.getPacksize());
    }

}

//槽函数：登出
void LiveMasterWidget::on_logout_call_signal(const QString & msg)
{
    QMessageBox::critical(this,"登出提示", msg);
    exit(EXIT_SUCCESS);
}

//槽函数：截屏信号
void LiveMasterWidget::onPixCaptured(QPixmap pix)
{
    QPixmap pix2=pix;
    pix2=pix2.scaled(ui->label->size());
    ui->label->setPixmap(pix2);

    //pix转字节流
    QByteArray byteArr;
    QBuffer buffer(&byteArr);
    buffer.open(QIODevice::WriteOnly);

    if(!pix.save(&buffer, "jpg", 100)){
        qDebug() << "LiveMasterWidget::onPixCaptured   文件转储失败!!!";
    }

    buffer.close();
    //组包
    int size=byteArr.size();
    const int one=4000;
    int total= std::ceil(size*1.0/one);

    for(int packno=0 ; packno<total ; packno++){
        int bufCnt=4;
        Pack pack;
        pack.setType(VIDEO);
        bufCnt+=4;
        pack.setFrame(CALL);
        bufCnt+=4;
        //特殊处理
        //房间号
        memcpy((char*)&pack+bufCnt, &houseID, 4);
        bufCnt+=4;
        //图片编号
        memcpy((char*)&pack+bufCnt, &picid, 4);
        bufCnt+=4;
        //总包数
        memcpy((char*)&pack+bufCnt, &total, 4);
        bufCnt+=4;
        //当前包号
        memcpy((char*)&pack+bufCnt, &packno, 4);
        bufCnt+=4;
        if(packno == total-1){
            //buffer长度
            int left=size-(total-1)*one;
            memcpy((char*)&pack+bufCnt, &left, 4);
            bufCnt+=4;
            //buffer内容
            memcpy((char*)&pack+bufCnt, (char*)byteArr.data()+one*packno,left);
            bufCnt+=left;
        }else{
            //buffer长度
            memcpy((char*)&pack+bufCnt, &one, 4);
            bufCnt+=4;
            //buffer内容
            memcpy((char*)&pack+bufCnt, (char*)byteArr.data()+one*packno,one);
            bufCnt+=one;
        }
        pack.setPacksize(bufCnt);

        session->send((char*)&pack, pack.getPacksize());
    }
}


